/* Copyright 2001,2002,2003 NAH6
 * All Rights Reserved
 *
 * Parts Copyright DoD, Parts Copyright Starium
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include "celpfilt.h"

/**************************************************************************
*
* ROUTINE
*		do_pfilt
*		do_pfilt_dynamic
*
* FUNCTION
*		pole filter - given a filter structure
*		do_pfilt uses static coefficients
*		do_pfilt_dynamic uses changing coefficients
*
* SYNOPSIS
*		subroutine do_pfilt(flt, data)
*		subroutine do_pfilt_dynamic(flt, coef, data)
*
*   formal 
*
*                       data    I/O
*       name            type    type    function
*       -------------------------------------------------------------------	
*	flt		FILTER	i/o	FILTER structure
*	coef		float	 i	coefficients
*	data		float	i/o	input/filtered output data	
*
***************************************************************************
*       
* DESCRIPTION
*
*	Recursive all-pole in-place time-domain filter.
*	The transfer function 1/A(z) is implemented
*	in a direct form realisation.
*
*                   N       -i
*       H(z) = 1 / SUM a(i)z         with a(0) = +1.0
*                  i=0
*
*	NOTE:  a(0) is not used for the actual computing,
*	as can easily be seen in the following flow graph.
*
*       x(t) ->---+------->--------(z0)-----> y(t)
*                 |                  |
*                 +-------< -a1 ----z1
*                 |                  |
*                 +-------< -a2 ----z2
*                 |                  |
*                 :                  :
*                 |                  |
*                 +-------< -aN ----zN
*
*
***************************************************************************
*
* CALLED BY
*
*	FindAdaptResidual FindLPCResidual UpdateEverything
*	HPF_InSpeech HPF_OutSpeech LPC_Synthesis PostFilter
*
***************************************************************************/

void do_pfilt(
FILTER *flt,
float data[])
{
  int t, j;

  if (flt->coef[0] != 1.0)
  {
    printf("polefilt:  bad coefficients\n");
    exit(1);
  }

  for (t = 0; t < flt->data_length; t++)
  {
    flt->memory[0] = data[t];
    for (j = flt->order; j > 0; j--)
    {
      flt->memory[0] -= flt->coef[j] * flt->memory[j];
      flt->memory[j]  = flt->memory[j-1];
    }
    data[t] = flt->memory[0];
  }
}

void do_pfilt_dynamic(
FILTER 	*flt,
float	coef[],
float 	data[])
{
  int t, j;

  if (coef[0] != 1.0)
  {
    printf("polefilt:  bad coefficients\n");
    exit(1);
  }

  for (t = 0; t < flt->data_length; t++)
  {
    flt->memory[0] = data[t];
    for (j = flt->order; j > 0; j--)
    {
      flt->memory[0] -= coef[j] * flt->memory[j];
      flt->memory[j]  = flt->memory[j-1];
    }
    data[t] = flt->memory[0];
  }
}
